home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.misc
- X-UNIX-From: nsayer@uop.uop.edu
- organization: University of the Pacific, Stockton, CA [138.9.200.1]
- subject: v15i048: Root-shell giver -- new and improved "su"
- from: mrapple@quack.sac.ca.us (Nick Sayer)
- Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
-
- Posting-number: Volume 15, Issue 48
- Submitted-by: mrapple@quack.sac.ca.us (Nick Sayer)
- Archive-name: sec/part01
-
- [Uses syslog and is otherwise BSD-specific; however, it should not be too
- difficult to convert to System V.
-
- I must admit that giving each user who is permitted to use root a password
- that only works for that user is an improvement over the standard "su" model,
- and certainly over a program that was in use on ncoast some years ago. But
- remember that giving *anyone* other than the system administrator the ability
- to access root is a potential security hole; as always, consider carefully
- before allowing someone root access. ++bsa]
-
- I'm not quite sure what to call this, but I call it "sec." Anyway,
- I've had a couple requests for it, so I thought I'd pass it along.
-
- #!/bin/sh
- # This is a shell archive (produced by shar 3.49)
- # To extract the files from this archive, save it to a file, remove
- # everything above the "!/bin/sh" line above, and type "sh file_name".
- #
- # made 10/08/1990 19:39 UTC by nsayer@uop
- # Source directory /files/users/staff-uop/nsayer/sec
- #
- # existing files will NOT be overwritten unless -c is specified
- #
- #
- #
- #
- # This shar contains:
- # length mode name
- # ------ ---------- ------------------------------------------
- # 1315 -rw-r--r-- sec.c
- # 1672 -rw-r--r-- secpw.c
- # 737 -rw-r--r-- Makefile
- # 1803 -rw-r--r-- README
- # 796 -rw-r--r-- config.h
- #
- if test -r _shar_seq_.tmp; then
- echo 'Must unpack archives in sequence!'
- echo Please unpack part `cat _shar_seq_.tmp` next
- exit 1
- fi
- # ============= sec.c ==============
- if test -f 'sec.c' -a X"$1" != X"-c"; then
- echo 'x - skipping sec.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting sec.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'sec.c' &&
- /*
- X *
- X * sec.c
- X *
- X * Grudgingly give out root shells to authorized users.
- X *
- X * Usage: sec
- X *
- X */
- X
- #include <stdio.h>
- #include <syslog.h>
- #include <strings.h>
- #include "config.h"
- X
- int getline(file,s)
- FILE *file;
- char *s;
- {
- X while (((*s=getc(file))!=EOF) && (*s!='\n')) s++;
- X if ((*s)==EOF) return 0;
- X *s=0;
- X return 1;
- }
- X
- extern char *crypt();
- X
- char ckpw(b)
- char *b;
- {
- X char *a,*encr,input[10];
- X int f;
- X
- X if (!strlen(b))
- X {
- X printf("Null PW. Please use 'secpw' and add one.\n");
- X return 1;
- X }
- X strcpy(input,getpass("Password:"));
- X encr=crypt(input,b);
- X return(!strcmp(encr,b));
- }
- X
- main()
- {
- X FILE* f;
- X char str[80],ok=0;
- X
- X f=fopen(FILENAME,"r");
- X if (f!=NULL)
- X {
- X while(getline(f,str))
- X {
- X char b[16],*c;
- X c=index(str,':');
- X if (c==NULL) continue;
- X strcpy(b,c+1);
- X *c='\0';
- X if (!strcmp(str,getlogin()))
- X if (ckpw(b))
- X ok=1;
- X }
- X fclose(f);
- X }
- X else
- X {
- X printf("Error reading file.\n");
- X exit(1);
- X }
- X
- X openlog("sec",0,LOG_FACILITY);
- X
- X if (ok)
- X {
- X syslog(LOG_OK_PRI,"security access: %s",getlogin());
- X seteuid(0);
- X setegid(0);
- X setuid(0);
- X setgid(0);
- X execl("/bin/csh"," SEC",(char*)0);
- X }
- X else
- X {
- X syslog(LOG_FAIL_PRI,"security access DENIED: %s",getlogin());
- X printf("Not Authorized.\n");
- X }
- }
- SHAR_EOF
- chmod 0644 sec.c ||
- echo 'restore of sec.c failed'
- Wc_c="`wc -c < 'sec.c'`"
- test 1315 -eq "$Wc_c" ||
- echo 'sec.c: original size 1315, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= secpw.c ==============
- if test -f 'secpw.c' -a X"$1" != X"-c"; then
- echo 'x - skipping secpw.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting secpw.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'secpw.c' &&
- /*
- X *
- X * secpw.c
- X *
- X * Change passwords for the sec password file
- X *
- X * Usage: secpw [username]
- X *
- X * It may seem odd that users are allowed to change other people's
- X * passwords, and change their own without supplying the old password,
- X * but whoever runs this must already have a uid of root, so it
- X * really doesn't matter.
- X *
- X */
- X
- #include <stdio.h>
- #include <strings.h>
- #include <sys/file.h>
- #include "config.h"
- X
- extern long random();
- extern char *getlogin();
- extern long time();
- X
- char charset[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./";
- X
- char getline(file,s)
- FILE *file;
- char *s;
- {
- X while(((*s=getc(file))!=EOF) && (*s!='\n')) s++;
- X if ((*s)==EOF) return 1;
- X *s=0;
- X return 0;
- }
- X
- main(argc,argv)
- int argc;
- char **argv;
- {
- X
- X char key[9],salt[3],line[80],line2[80],*who,ok=0;
- X FILE *f1,*f2;
- X
- X if (setuid(0))
- X {
- X printf("Must be root.\n");
- X exit(1);
- X }
- X
- X who=getlogin();
- X if (argc>1)
- X who=*(argv+1);
- X
- X strcpy(key,getpass("New Password:"));
- X if (strcmp(key,getpass("Again:")))
- X {
- X printf("No Match.\n");
- X exit(1);
- X }
- X
- X srandom((int) time(0L));
- X salt[0]=charset[random()%strlen(charset)];
- X salt[1]=charset[random()%strlen(charset)];
- X strcpy(line,who);
- X strcat(line,":");
- X strcat(line,crypt(key,salt));
- X
- X umask(0377);
- X f1=fopen(FILENAME,"r");
- X f2=fopen(TEMPNAME,"w");
- X flock(fileno(f2),LOCK_EX);
- X while(!getline(f1,line2))
- X if (strncmp(line2,who,strlen(who)))
- X fprintf(f2,"%s\n",line2);
- X else
- X {
- X fprintf(f2,"%s\n",line);
- X ok++;
- X }
- X fclose(f1);
- X fclose(f2);
- X rename(TEMPNAME,FILENAME);
- X
- X if (!ok)
- X {
- X printf("Cannot change: User not authorized.\n");
- X exit(1);
- X }
- X
- }
- SHAR_EOF
- chmod 0644 secpw.c ||
- echo 'restore of secpw.c failed'
- Wc_c="`wc -c < 'secpw.c'`"
- test 1672 -eq "$Wc_c" ||
- echo 'secpw.c: original size 1672, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= Makefile ==============
- if test -f 'Makefile' -a X"$1" != X"-c"; then
- echo 'x - skipping Makefile (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting Makefile (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
- #
- # Makefile for sec
- #
- # To install: Patch config.h to change the location of the security filename.
- # Then make, su, and make install.
- # Then create the security file. See README
- #
- X
- #CC=/bin/cc
- X
- # for SunOS 4.0 and above, static binding is recommended. If sharing
- # a library by NFS, it may become disconnected, rendering sec unavailable.
- X
- CFLAGS= -O -Bstatic
- X
- GROUP=staff
- INSTALLDIR=/etc
- X
- all:sec secpw
- X
- sec:sec.o
- X $(CC) $(CFLAGS) -o sec sec.o
- X strip sec
- X
- secpw:secpw.o
- X $(CC) $(CFLAGS) -o secpw secpw.o
- X strip secpw
- X
- sec.o:sec.c config.h
- X
- secpw.o:secpw.c config.h
- X
- install:sec secpw
- X mv sec secpw $(INSTALLDIR)
- X cd $(INSTALLDIR)
- X chmod 4710 sec
- X chmod 710 secpw
- X chown root sec secpw
- X chgrp $(GROUP) sec secpw
- X
- clean:
- X rm -f *.o core
- SHAR_EOF
- chmod 0644 Makefile ||
- echo 'restore of Makefile failed'
- Wc_c="`wc -c < 'Makefile'`"
- test 737 -eq "$Wc_c" ||
- echo 'Makefile: original size 737, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= README ==============
- if test -f 'README' -a X"$1" != X"-c"; then
- echo 'x - skipping README (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting README (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'README' &&
- sec is a password protected means of allowing specified users to
- obtain a root shell without giving them the system's root password.
- It is similar in this regard to su, except that each user has his
- own password, which can be changed at any time. These passwords and
- authorized users are stored in a security file hidden cleverly
- somewhere on a mounted file system (at your descretion).
- X
- This is MARGINALLY safer than releasing the root password, but
- NOT MUCH. REMEMBER: When someone IS root they can do anything.
- This program, used improperly can be DANGEROUS! By itself, this
- source is not, since it must be run suid for it to work.
- X
- sec will log to syslog successful and unsuccessful attempts to
- get a root shell. If you don't have syslog, a phoney syslog
- routine is provided to log to a file.
- X
- The security file itself is owned by root and chmod'd to u+r (0400).
- The format is one user per line, the username, followed by a colon,
- followed by an optional crypted password. To add a user, simply add
- the user to the file, with the ":" as the last character on the line.
- Then either use secpw to set the password, or remind the user to do
- this the first time he uses sec (sec will warn when a user has a null
- PW, but will allow root access anyway).
- X
- secpw may be used to change someone else's security password, in case
- that user is compromised. secpw tries to setuid itself to root as a
- test to see if it is being run by root. Therefore you must NOT suid
- secpw. secpw will not run if it can't setuid(0), so to change your sec
- password, you first have to get into sec (or root), presumably using
- your old password.
- X
- As further protection, it is suggested that sec authorized users be placed
- into a separate "operator" or "sec" group, and that only this group be
- allowed to even run sec (chmod o-rwx).
- SHAR_EOF
- chmod 0644 README ||
- echo 'restore of README failed'
- Wc_c="`wc -c < 'README'`"
- test 1803 -eq "$Wc_c" ||
- echo 'README: original size 1803, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= config.h ==============
- if test -f 'config.h' -a X"$1" != X"-c"; then
- echo 'x - skipping config.h (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting config.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'config.h' &&
- /*
- X *
- X * config.h for sec/secpw
- X *
- X */
- X
- /*
- X
- The first three definitions are for syslog. The first is the logging
- facility code to use. LOG_FAIL_PRI is the priority to use when logging
- a failure in authorization message. I.e. mistyped password, unauthorized
- user, etc. LOG_OK_PRI is the priority to use when logging a successful
- attempt.
- X
- */
- X
- #define LOG_FACILITY LOG_AUTH
- #define LOG_FAIL_PRI LOG_WARNING
- #define LOG_OK_PRI LOG_NOTICE
- X
- /*
- X
- The next definition is the location of the security file, and the temporary
- file for secpw to use. the temp file MUST be on the same file system as
- the real file. rename() is used to move the temp to the real one when
- the change is done. Just like vipw.
- X
- */
- X
- #define FILENAME "/usr/adm/security"
- #define TEMPNAME "/usr/adm/security.tmp"
- #include <stdio.h>
- SHAR_EOF
- chmod 0644 config.h ||
- echo 'restore of config.h failed'
- Wc_c="`wc -c < 'config.h'`"
- test 796 -eq "$Wc_c" ||
- echo 'config.h: original size 796, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- exit 0
- --
- Nick Sayer | Disclaimer:
- N6QQQ | "Just because you're reading my post doesn't
- mrapple@quack.sac.ca.us | mean we're gonna take long showers together."
- 209-952-5347 (Telebit) | -- Gunnery Sgt. Thomas Highway
-
-